<template>
  <gg-form-item :tip="tip" :label="label" :must="must" :message="message" :messageDisplay="messageDisplay" :labelWidth="localLabelWidth" layout="col"
    :input-value="localVal">
    <view class="gg-editor">
      <view class='toolbar' @tap="format">
        <view :class="formats.bold ? 'ql-active' : ''" class="iconfont icon-zitijiacu" data-name="bold"></view>
        <view :class="formats.italic ? 'ql-active' : ''" class="iconfont icon-zitixieti" data-name="italic"></view>
        <view :class="formats.underline ? 'ql-active' : ''" class="iconfont icon-zitixiahuaxian" data-name="underline"></view>
        <view :class="formats.strike ? 'ql-active' : ''" class="iconfont icon-zitishanchuxian" data-name="strike"></view>
        <view :class="formats.align === 'left' ? 'ql-active' : ''" class="iconfont icon-zuoduiqi" data-name="align" data-value="left"></view>
        <view :class="formats.align === 'center' ? 'ql-active' : ''" class="iconfont icon-juzhongduiqi" data-name="align" data-value="center"></view>
        <view :class="formats.align === 'right' ? 'ql-active' : ''" class="iconfont icon-youduiqi" data-name="align" data-value="right"></view>
        <view :class="formats.align === 'justify' ? 'ql-active' : ''" class="iconfont icon-zuoyouduiqi" data-name="align" data-value="justify"></view>
        <view :class="formats.lineHeight ? 'ql-active' : ''" class="iconfont icon-line-height" data-name="lineHeight" data-value="2"></view>
        <view :class="formats.letterSpacing ? 'ql-active' : ''" class="iconfont icon-Character-Spacing" data-name="letterSpacing" data-value="2em">
        </view>
        <view :class="formats.marginTop ? 'ql-active' : ''" class="iconfont icon-722bianjiqi_duanqianju" data-name="marginTop" data-value="20px">
        </view>
        <view :class="formats.previewarginBottom ? 'ql-active' : ''" class="iconfont icon-723bianjiqi_duanhouju" data-name="marginBottom"
          data-value="20px"></view>
        <view class="iconfont icon-clearedformat" @tap="removeFormat"></view>
        <view :class="formats.fontFamily ? 'ql-active' : ''" class="iconfont icon-font" data-name="fontFamily" data-value="Pacifico"></view>
        <view :class="formats.fontSize === '24px' ? 'ql-active' : ''" class="iconfont icon-fontsize" data-name="fontSize" data-value="24px"></view>
        <view :class="formats.color === '#0000ff' ? 'ql-active' : ''" class="iconfont icon-text_color" data-name="color" data-value="#0000ff"></view>
        <view :class="formats.backgroundColor === '#00ff00' ? 'ql-active' : ''" class="iconfont icon-fontbgcolor" data-name="backgroundColor"
          data-value="#00ff00"></view>
        <view class="iconfont icon-date" @tap="insertDate"></view>
        <view class="iconfont icon--checklist" data-name="list" data-value="check"></view>
        <view :class="formats.list === 'ordered' ? 'ql-active' : ''" class="iconfont icon-youxupailie" data-name="list" data-value="ordered"></view>
        <view :class="formats.list === 'bullet' ? 'ql-active' : ''" class="iconfont icon-wuxupailie" data-name="list" data-value="bullet"></view>
        <view class="iconfont icon-undo" @tap="undo"></view>
        <view class="iconfont icon-redo" @tap="redo"></view>
        <view class="iconfont icon-outdent" data-name="indent" data-value="-1"></view>
        <view class="iconfont icon-indent" data-name="indent" data-value="+1"></view>
        <view class="iconfont icon-fengexian" @tap="insertDivider"></view>
        <view class="iconfont icon-charutupian" @tap="insertImage"></view>
        <view :class="formats.header === 1 ? 'ql-active' : ''" class="iconfont icon-format-header-1" data-name="header" :data-value="1"></view>
        <view :class="formats.script === 'sub' ? 'ql-active' : ''" class="iconfont icon-zitixiabiao" data-name="script" data-value="sub"></view>
        <view :class="formats.script === 'super' ? 'ql-active' : ''" class="iconfont icon-zitishangbiao" data-name="script" data-value="super"></view>
        <view class="iconfont icon-shanchu" @tap="clear"></view>
        <view :class="formats.direction === 'rtl' ? 'ql-active' : ''" class="iconfont icon-direction-rtl" data-name="direction" data-value="rtl">
        </view>
      </view>

      <editor id="editor" class="ql-container" :placeholder="placeholder" showImgSize showImgToolbar showImgResize @statuschange="onStatusChange"
        :read-only="readOnly" @ready="onEditorReady" @blur="onBlur">
      </editor>
    </view>
    <helang-compress ref="helangCompress"></helang-compress>
  </gg-form-item>
</template>

<script>
import MixinsCommon from '../mixins/mixins-common.js';
import helangCompress from './compressImage'
export default {
  mixins: [MixinsCommon],
  components: {
    helangCompress
  },
  name: "GgEditor",
  inject: {
    ggFormGroup: {
      default() {
        return null
      }
    }
  },
  props: {
    value: {
      type: String,
      default: ""
    },
    tip: {
      type: String,
      default: ""
    },

    message: {
      type: String,
      default: ""
    },
    messageDisplay: {
      type: Boolean,
      default: false
    },
    placeholder: {
      type: String,
      default() {
        return '开始输入...';
      }
    },
    upload: {
      type: Object,
      default() {
        return {
          connectionCount: 1,
          leaveConfirm: '正在上传文件',
          maxSize: 1080,
          quality: 80
        }
      }
    }
  },
  data() {
    return {
      localVal: '',
      readOnly: false,
      formats: {},
      upload_progress: null,
    };
  },
  watch: {
    value(newVal) {
      this.localVal = newVal;
      this.setContents();
    }
  },
  created: function () {
    this.localVal = this.value;
    /* uni.loadFontFace({
      family: 'Pacifico',
      source: 'url("https://sungd.github.io/Pacifico.ttf")'
    }) */
    // console.log(this.upload)
  },
  methods: {
    onBlur(e) {
      this.getContents();
    },
    /* 保存内容 */
    getContents() {
      this.editorContext.getContents({
        success: (res) => {
          this.localVal = res.html;
          this.$emit('input', this.localVal);
        }
      })
    },
    readOnlyChange() {
      this.readOnly = !this.readOnly
    },
    onEditorReady() {
      uni.createSelectorQuery().in(this).select('#editor').context((res) => {
        this.editorContext = res.context;
        this.setContents();
        // console.log('初始化完成')
      }).exec()
    },
    setContents() {
      this.editorContext.setContents({
        html: this.localVal
      })
    },
    undo() {
      this.editorContext.undo()
    },
    redo() {
      this.editorContext.redo()
    },
    format(e) {
      let {
        name,
        value
      } = e.target.dataset
      if (!name) return
      this.editorContext.format(name, value)
    },
    onStatusChange(e) {
      const formats = e.detail
      this.formats = formats
    },
    insertDivider() {
      this.editorContext.insertDivider({
        success: function () {
          // console.log('insert divider success')
        }
      })
    },
    clear() {
      this.editorContext.clear({
        success: function (res) {
          // console.log("clear success")
        }
      })
    },
    removeFormat() {
      this.editorContext.removeFormat()
    },
    insertDate() {
      const date = new Date()
      const formatDate = `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`
      this.editorContext.insertText({
        text: formatDate
      })
    },
    /* 插入图片 ，可批量插入 */
    insertImage() {
      uni.chooseImage({
        count: this.upload.connectionCount || 1,
        success: (res) => {
          /* 图片选择成功，开始循环执行上传任务 */
          this.imgUploadQueue(res.tempFiles, 0);
        }
      })
    },
    /* 多图上传队列处理，若有图片上传失败则清空所有等待中图片 */
    imgUploadQueue(images, key) {
      let showLoading_title = this.upload.leaveConfirm ? this.upload.leaveConfirm + '：' : '';
      showLoading_title += this.upload_progress === null ? '' : '(' + this.upload_progress + '%)';
      showLoading_title += (parseInt(key) + 1) + '/' + images.length;
      // console.log(showLoading_title);
      uni.showLoading({
        title: showLoading_title
      });
      this.imgUpload(images[key]).then((result) => {
        this.editorContext.insertImage({
          src: result.src,
          alt: images[key].name,
          success: () => {
            // console.log('insert image success')
            if (images.length > ++key) {
              this.imgUploadQueue(images, key)
            } else {
              uni.hideLoading();
              this.getContents();
            }
          }
        })
      }).catch(error => {
        console.error(error.msg)
        uni.showToast({
          title: error.msg,
          duration: 2000,
          icon: 'none'
        });
      });

    },
    /* 上传图片 */
    imgUpload(file) {
      this.upload_progress = null;
      let return_data = {
        error: 0,
        msg: '',
        src: ''
      }
      const upload = this.upload;
      return this.compressImage(file).then((fileUrl) => {
        if (upload.url) {
          return new Promise((resolve, reject) => {
            const uploadTask = uni.uploadFile({
              url: upload.url, //仅为示例，非真实的接口地址
              filePath: fileUrl,
              name: upload.fileKey || 'file',
              formData: upload.params,
              success: (uploadFileRes) => {
                uploadFileRes.data = JSON.parse(uploadFileRes.data);
                //  console.log(uploadFileRes.data)
                if (uploadFileRes.statusCode !== 200 || uploadFileRes.data.error) {
                  return_data.msg = uploadFileRes.data.msg
                  return_data.error = uploadFileRes.data.error
                  reject(return_data);
                } else {
                  return_data.src = uploadFileRes.data.save_domain + '/' + uploadFileRes.data.save_domain.save_url
                  resolve(return_data);
                }
              },
              fail: (fail) => {
                // console.log(fail)
                return_data.msg = fail.msg || '图片上传失败'
                return_data.error = 1
                reject(return_data);
              }
            });
            uploadTask.onProgressUpdate((res) => {
              // console.log('上传进度' + res.progress);
              this.upload_progress = res.progress;
              // console.log('已经上传的数据长度' + res.totalBytesSent);
              // console.log('预期需要上传的数据总长度' + res.totalBytesExpectedToSend);

              // 测试条件，取消上传任务。

            });
          })
        } else {
          console.warn('因：没有图片资源接口路径，故：直接转为base64使用。生成环境建议使用图片接口地址保存图片并返回地址。');
          // #ifdef MP-WEIXIN
          return new Promise((resolve, reject) => {
            uni.getFileSystemManager().readFile({
              filePath: fileUrl, //选择图片返回的相对路径
              encoding: 'base64', //编码格式
              success: res => { //成功的回调
                // console.log(res);
                let base64 = 'data:' + file.type + ';base64,' + res.data //不加上这串字符，在页面无法显示的哦
                return_data.src = base64;
                resolve(return_data);
              }, fail: (e) => {
                return_data.msg = '图片转换失败'
                return_data.error = 1
                reject(return_data);
              }
            })
          })
          // #endif

          // #ifndef MP-WEIXIN
          return new Promise((resolve, reject) => {
            uni.request({
              url: fileUrl,
              method: 'GET',
              responseType: 'arraybuffer',
              success: ress => {
                let base64 = uni.arrayBufferToBase64(ress.data); //把arraybuffer转成base64 
                return_data.src = 'data:' + file.type + ';base64,' + base64////不加上这串字符，在页面无法显示的哦
                resolve(return_data);
              }, fail: (e) => {
                return_data.msg = '图片转换失败'
                return_data.error = 1
                reject(return_data);
              }
            })
          })
          // #endif
        }
      })
    },
    /* 压缩图片 */
    compressImage(file) {
      return new Promise((resolve, reject) => {
        if (this.upload.quality < 100) {
          // console.log('压缩图片')
          let fileType = file.type.split('/')[1];
          fileType = fileType == 'jpeg' ? 'jpg' : fileType;
          this.$refs.helangCompress.compress({
            src: file.path,
            maxSize: this.upload.maxSize || 1080,
            fileType: file.type,
            quality: (this.upload.quality || 80) / 100
          }).then((res) => {
            // console.log('压缩成功')
            // console.log(res);
            // console.log('返回压缩后的图片地址');
            resolve(res);
          }).catch((err) => {
            console.error(err)
            reject(err)
          });
        } else {
          //不压缩直接返回
          resolve(file.path)
        }
      });

      // console.log('返回压缩后的图片地址')
      // return newFileUrl;
    }
  }
};
</script>
<style>
@import "./editor-icon.css";
.wrapper {
  padding: 5px;
}
.iconfont {
  display: inline-block;
  padding: 8px 8px;
  width: 24px;
  height: 24px;
  cursor: pointer;
  font-size: 20px;
}
.toolbar {
  box-sizing: border-box;
  border-bottom: 0;
  font-family: "Helvetica Neue", "Helvetica", "Arial", sans-serif;
}
.ql-container {
  box-sizing: border-box;
  padding: 5px;
  width: 100%;
  min-height: 30vh;
  height: auto;
  background: #f1f1f166;
  margin-top: 20px;
  font-size: 16px;
  line-height: 1.5;
}
.ql-active {
  color: #06c;
}
</style>
